package com.jintu.portal.service.datadriver;

import com.alibaba.fastjson.JSONObject;
import com.jintu.portal.config.SysConfigurer;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.IOException;
import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Random;
import java.util.UUID;

@Slf4j
@Component("dataRequestDriver")
public class DataRequestDriver {

    @Resource(name = "sysConfigurer")
    private SysConfigurer sysConfigurer;

    // 鄂车数据系统接口请求URL
//    public static final String SYS_URL = "http://120.55.53.191/echedata/query";
    public static final String SYS_URL = "http://47.93.251.144:8081/datadriver/query";
//    public static final String SYS_URL = "http://localhost:8081/datadriver/query";
    // 商户秘钥
    private static final String MERCH_KEY = "fe61fef4-a472-46c3-983d-1b454b277233";
    // 商户私钥(可以不填)
    private static final String MERCH_PRIVATE = "MyPrivate" + UUID.randomUUID().toString();

    public String sendUnionPayDoka(String name, String idNo) throws Exception{
        return sendRequest(
                "Risk" + System.nanoTime(),
                "M100000094",
                MERCH_PRIVATE,
                "ECP100038",
                "{\n" +
                        "\t\"industryType\": \"C8\",\n" +
                        "\t\"idNo\": \"" + idNo +"\",\n" +
                        "\t\"idName\": \""+ name +"\",\n" +
                        "\t\"idSecretType\": \"N\",\n" +
                        "\t\"bankCardSecretType\": \"N\"" +
                        "}" // 请求的jsonStr
        );
    }

    public String sendPersonalInfo(String name, String idNo) throws Exception{
        return sendRequest(
                "Risk" + System.nanoTime(),
                "M100000094",
                MERCH_PRIVATE,
                "ECP100039",
                "{\n" +
                        "\t\"idCard\": \"" + idNo +"\",\n" +
                        "\t\"name\": \""+ name +"\",\n" +
                        "}" // 请求的jsonStr
        );
    }

    /**
     * 获取驾驶证信息
     * @param name
     * @param idNo
     * @return
     * @throws Exception
     */
    public String getUserlicenseInfo(String name, String idNo) throws Exception{
        return sendRequest(
                "Risk" + System.nanoTime(),
                "M100000094",
                MERCH_PRIVATE,
                "ECP100040",
                "{\n" +
                        "\t\"industryType\": \"C8\",\n" +
                        "\t\"idNo\": \"" + idNo +"\",\n" +
                        "\t\"idName\": \""+ name +"\",\n" +
                        "\t\"idSecretType\": \"N\",\n" +
                        "\t\"bankCardSecretType\": \"N\"" +
                        "}" // 请求的jsonStr
        );
    }

    public String DCBlacklist(String name, String idNo, String phone) throws Exception{
        return sendRequest(
                "Risk" + System.nanoTime(),
                "M100000094",
                MERCH_PRIVATE,
                "ECP100001",
                "{\n" +
                        "\t\"idCard\": \"" + idNo +"\",\n" +
                        "\t\"name\": \""+ name +"\",\n" +
                        "\t\"phone\": \""+ phone +"\"" +
                        "}" // 请求的jsonStr
        );
    }

    /**
     * 魔杖多头
     * @param name
     * @param idNo
     * @param phone
     * @return
     * @throws Exception
     */
    public String sendMoXieMulti(String name, String idNo, String phone) throws Exception{
        return sendRequest(
                "Risk" + System.nanoTime(),
                "M100000094",
                MERCH_PRIVATE,
                "P100039",
                "{\n" +
                        "\t\"idcard\": \"" + idNo +"\",\n" +
                        "\t\"name\": \""+ name +"\",\n" +
                        "\t\"mobile\": \""+ phone +"\"" +
                        "}" // 请求的jsonStr
        );
    }

    /**
     * 宜信欺诈甄别
     * @param name
     * @param idNo
     * @param phone
     * @return
     * @throws Exception
     */
    public String sendYXFakeFind(String name, String idNo, String phone) throws Exception{
        return sendRequest(
                "Risk" + System.nanoTime(),
                "M100000094",
                MERCH_PRIVATE,
                "P100036",
                "{\n" +
                        "\t\"amountBusiness\": \"0\",\n" +
                        "\t\"apiName\": \"fraud.screening.advance.api\",\n" +
                        "\t\"idNo\": \"" + idNo +"\",\n" +
                        "\t\"name\": \""+ name +"\",\n" +
                        "\t\"mobile\": \""+ phone +"\"" +
                        "}" // 请求的jsonStr
        );
    }

    /**
     * 宜信小额分
     * @param name
     * @param idNo
     * @param phone
     * @return
     * @throws Exception
     */
    public String sendYXSmallScore(String name, String idNo, String phone) throws Exception{
        return sendRequest(
                "Risk" + System.nanoTime(),
                "M100000094",
                MERCH_PRIVATE,
                "P100040",
                "{\n" +
                        "\t\"amountBusiness\": \"0\",\n" +
                        "\t\"apiName\": \"decision.report.pro.bt.api\",\n" +
                        "\t\"idNo\": \"" + idNo +"\",\n" +
                        "\t\"name\": \""+ name +"\",\n" +
                        "\t\"mobile\": \""+ phone +"\"" +
                        "}" // 请求的jsonStr
        );
    }

    /**
     * 51营销分
     * @param name
     * @param idNo
     * @param phone
     * @return
     * @throws Exception
     */
    public String send51MarketingScore(String name, String idNo, String phone, String orderId) throws Exception{
        return sendRequest(
                "Risk" + System.nanoTime(),
                "M100000094",
                MERCH_PRIVATE,
                "P100038",
                "{\n" +
                        "\t\"orderSn\": \"" + getFormatTime() + getRandomString(15) +"\",\n" +
                        "\t\"timestamp\": \"" + System.currentTimeMillis() +"\",\n" +
                        "\t\"idCard\": \"" + idNo +"\",\n" +
                        "\t\"name\": \""+ name +"\",\n" +
                        "\t\"mobile\": \""+ phone +"\"" +
                        "}" // 请求的jsonStr
        );
    }

    /**
     * 天创信用探针
     * @param name
     * @param idNo
     * @param phone
     * @return
     * @throws Exception
     */
    public String sendTCCreditPointScan(String name, String idNo, String phone, String cardNo) throws Exception{
        return sendRequest(
                "Risk" + System.nanoTime(),
                "M100000094",
                MERCH_PRIVATE,
                "P100037",
                "{\n" +
                        "\t\"idCard\": \"" + idNo +"\",\n" +
                        "\t\"name\": \""+ name +"\",\n" +
                        "\t\"mobile\": \""+ phone +"\"" +
                        "}" // 请求的jsonStr
        );
    }

    /**
     * 新颜信用行为雷达
     * @param name
     * @param idNo
     * @param phone
     * @return
     * @throws Exception
     */
    public String getXinYanActionScan(String name, String idNo, String phone, String cardNo) throws Exception{
        return sendRequest(
                "Risk" + System.nanoTime(),
                "M100000094",
                MERCH_PRIVATE,
                "P100033",
                "{\n" +
                        "\t\"industryType\": \"C8\",\n" +
                        "\t\"idNo\": \"" + idNo +"\",\n" +
                        "\t\"idName\": \""+ name +"\",\n" +
                        "\t\"phoneNo\": \""+ phone +"\",\n" +
                        "\t\"bankcardNo\": \""+ cardNo +"\"" +
                        "}" // 请求的jsonStr
        );
    }

    public String sendCardLocation(String bankNo) throws Exception{
        return sendRequest(
                "Risk" + System.nanoTime(),
                "M100000094",
                MERCH_PRIVATE,
                "P100030",
                "{\n" +
                        "\t\"bankCard\": \"" + bankNo +"\"" +
                        "}" // 请求的jsonStr
        );
    }

    /**
     * 魔蝎2.0 - 多头报告
     * @param name
     * @param idcard
     * @param mobile
     * @return
     * @throws Exception
     */
        public String getMoXieMultiInfo(String name, String idcard, String mobile) throws Exception{
        return sendRequest(
                "Risk" + System.nanoTime(),
                "M100000094",
                MERCH_PRIVATE,
                "P100039",
                "{\n" +
                        "\t\"industryType\": \"C8\",\n" +
                        "\t\"idcard\": \"" + idcard +"\",\n" +
                        "\t\"name\": \""+ name +"\",\n" +
                        "\t\"mobile\": \""+ mobile +"\",\n" +
                        "\t\"idSecretType\": \"N\",\n" +
                        "\t\"bankCardSecretType\": \"N\"" +
                        "}" // 请求的jsonStr
        );
    }

    /*
     * @Author cyx
     * @Description 获取宝盒信息
     * @Date 18:54 2019/6/4
     * @Param [name, idNo, phone]
     * @return java.lang.String
     **/
    public String getTreasureBox(String name, String idcard, String mobile) throws Exception{
        return sendRequest(
                "Risk" + System.nanoTime(),
                "M100000094",
                MERCH_PRIVATE,
                "P100041",
                "{\n" +
                        "\t\"idcard\": \"" + idcard +"\",\n" +
                        "\t\"name\": \""+ name +"\",\n" +
                        "\t\"mobile\": \""+ mobile +"\"" +
                        "}" // 请求的jsonStr
        );
    }

    /*
     * @Author cyx
     * @Description 获取小宝分信息
     * @Date 15:45 2019/6/5
     * @Param [name, idcard, mobile]
     * @return java.lang.String
     **/
    public String getXiaoBaoScore(String name, String idcard, String mobile) throws Exception{
        return sendRequest(
                "Risk" + System.nanoTime(),
                "M100000094",
                MERCH_PRIVATE,
                "P100042",
                "{\n" +
                        "\t\"idcard\": \"" + idcard +"\",\n" +
                        "\t\"name\": \""+ name +"\",\n" +
                        "\t\"mobile\": \""+ mobile +"\"" +
                        "}" // 请求的jsonStr
        );
    }

    /*
     * @Author cyx
     * @Description 获取有盾信息
     * @Date 17:49 2019/7/12
     * @Param [idcard]
     * @return java.lang.String
     **/
    public String getShields(String idcard) throws Exception{
        return sendRequest(
                "Risk" + System.nanoTime(),
                "M100000094",
                MERCH_PRIVATE,
                "P100043",
                "{\n" +
                        "\t\"idcard\": \"" + idcard +"\",\n" +
                        "}" // 请求的jsonStr
        );
    }

    /**
     * 向系统发送数据产品请求
     *
     * @param orderId 订单号
     * @param jsonStr 参数串
     * @param productCode 产品编号
     * @return 请求结果
     */
    public static String sendRequest(
            String orderId,
            String merchCode,
            String merchPrivate,
            String productCode,
            String jsonStr) throws Exception {
        String tranTime = String.valueOf(System.nanoTime());
        // 创建POST请求的参数键值对。
        JSONObject argsJson = new JSONObject();
        // 订单号：请务必保持不不⼀一致，否则会订单重复（必填）
        argsJson.put("orderId", orderId);
        // 商户号：由也⽣生统⼀一提供给商户（必填）
        argsJson.put("merchCode", merchCode);
        // 产品号：需要请求的数据产品编号（必填）
        argsJson.put("productCode", productCode);
        // 时间戳：发起请求的时间戳
        argsJson.put("tranTime", tranTime);
        // 请求参数：请求的参数是以json格式的字符串串组成
        argsJson.put("jsonStr", jsonStr);
        // merchPrivate参数
        if (StringUtils.isNotBlank(merchPrivate)) {
            argsJson.put("merchPrivate", merchPrivate);
        }
        // 签名串串：对请求数据的签名字符串串
        String sign = generateSign(orderId, merchCode, productCode, merchPrivate,
                jsonStr, tranTime, MERCH_KEY);
        argsJson.put("sign", sign);
        // 将参数加⼊入POST请求中。
        return jsonPost(argsJson.toJSONString());
    }

    /**
     * 对请求数据进行签名
     *
     * @param productCode 数据产品编号
     * @param merchCode 商户编号
     * @param jsonStr 请求数据字符串串
     * @param merchKey 商户Key
     * @param orderId 订单号
     * @param tranTime 时间戳
     * @return 签名串串
     */
    private static String generateSign(
            String orderId,
            String merchCode,
            String productCode,
            String merchPrivate,
            String jsonStr,
            String tranTime,
            String merchKey) throws Exception {
        StringBuilder strBuilder = new StringBuilder();
        strBuilder.append(merchCode);
        strBuilder.append(orderId);
        strBuilder.append(productCode);
        strBuilder.append(jsonStr);
        if (merchPrivate != null) {
            strBuilder.append(merchPrivate);
        }
        strBuilder.append(tranTime);
        strBuilder.append(merchKey);
        return cryptoWithMD5(strBuilder.toString());
    }

    /**
     * 使用的MD5加密 - 先MD5，之后转为小写
     * @param data 待加密数据
     * @return 加密完成结果
     */
    private static String cryptoWithMD5(String data)
            throws Exception {
        MessageDigest MD5 = MessageDigest.getInstance("MD5");
        byte[] bytes;
        if (MD5 == null) {
            throw new NoSuchAlgorithmException();
        }
        MD5.update(data.getBytes("UTF-8"));
        bytes = MD5.digest();
        MD5.reset();
        StringBuilder builder = new StringBuilder();
        for (byte b : bytes) {
            int i = b;
            if (i < 0) {
                i += 256;
            }
            if (i < 16) {
                builder.append("0");
            }
            builder.append(Integer.toHexString(i));
        }
        return builder.toString();// 32位的加密
    }

    private static String jsonPost(String parameters) {
        HttpPost post = new HttpPost(SYS_URL);
        post.addHeader("Content-type", "application/json; charset=utf-8");
        post.setHeader("Accept", "application/json");
        post.setEntity(new StringEntity(parameters, Charset.forName("UTF-8")));
        HttpResponse response;
        try {
            CloseableHttpClient httpClient = HttpClientBuilder.create().build();
            response = httpClient.execute(post);
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode == HttpStatus.SC_OK) {
                return EntityUtils.toString(response.getEntity(), "UTF-8");
            } else {
                return null;
            }
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 生成n位随机数
     * @param n
     * @return
     */
    public String getRandomString(int n){
        String str="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        Random random=new Random();
        StringBuffer sb=new StringBuffer();
        for(int i=0;i< n;i++){
            int number=random.nextInt(62);
            sb.append(str.charAt(number));
        }
        return sb.toString();
    }

    /**
     * 获取当前时间戳
     * @return
     */
    public String getFormatTime() {
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS");
        LocalDateTime time = LocalDateTime.now();
        String localTime = df.format(time);
        return localTime;
    }
}